package jmine.tec.rpc.server.representation.representers.lazy;

import java.util.Arrays;
import java.util.Collections;

import jmine.tec.proxy.builder.ProxyBuilder;
import jmine.tec.proxy.chain.ChainElement;
import jmine.tec.rpc.common.entity.EntityRepresentation;
import jmine.tec.rpc.common.entity.EntityRest;
import jmine.tec.rpc.common.lazy.LazyRepresentation;
import jmine.tec.rpc.common.lazy.LazyRepresentationInitializer;
import jmine.tec.rpc.common.lazy.LazyRepresenterChain;
import jmine.tec.rpc.server.representation.RepresentationContext;
import jmine.tec.rpc.server.representation.representers.AbstractRepresenter;

/**
 * Representer lazy, devolve um proxy para a representação real, que só é criada quando necessário.
 * 
 * @author lundberg
 * @param <R>
 */
public class LazyRepresenter<R extends EntityRepresentation> extends AbstractRepresenter<R, LazyPersistableBean> {

    private final EntityRest<R> service;

    /**
     * Construtor
     * 
     * @param representationClass representationClass
     * @param service service
     */
    public LazyRepresenter(Class<R> representationClass, EntityRest<R> service) {
        super(representationClass, LazyPersistableBean.class);
        this.service = service;
    }

    /**
     * {@inheritDoc}
     */
    public R represent(RepresentationContext context, LazyPersistableBean object) {
        LazyRepresentationInitializer initializer = new LazyRepresentationInitializer(this.service, object.getPersistable().getPk());
        ChainElement chain = new LazyRepresenterChain(initializer);

        ProxyBuilder builder = new ProxyBuilder();
        builder.setType(this.getRepresentationClass());
        builder.setChainElements(Collections.singletonList(chain));
        builder.setInterfaces(Arrays.asList(new Class<?>[]{ LazyRepresentation.class }));
        return this.getRepresentationClass().cast(builder.build());
    }
}
